classdef ziServerSweeperModuleData < EquipmentControl.ZI.ziServer.ziServerData.ziServerData
    %ZISERVERSWEEPERMODULEDATA Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
        sweep_device
        sweep_node
        sweep_value
    end
    
    methods
        function obj = ziServerSweeperModuleData(measured_data,nodeCell, sweep)
            %ZISERVERSWEEPERMODULEDATA Construct an instance of this class
            %   Detailed explanation goes here
            obj@EquipmentControl.ZI.ziServer.ziServerData.ziServerData('ziSweeperData', measured_data, nodeCell);
            obj.sweep_device = sweep.device;
            obj.sweep_node = sweep.node;
            obj.sweep_value = sweep.value;
        end
    end
    
    %%
    methods
        function data = getNodeData(obj, varargin)
            p=inputParser;
            p.addOptional('index', 1, @(x) ismember(x, 1:size(obj.data_node, 1)));
            p.parse(varargin{:});
            [data.x, data.y] = obj.get_data(obj.data_node{p.Results.index, [1 2]});
        end
        
        function [xList, yList] = getSweeperData(obj, varargin)
            p=inputParser;
            p.addOptional('index', 1, @(x) ismember(x, 1:size(obj.data_node, 1)));
            p.parse(varargin{:});
            
            [xList, yList] = obj.get_data(obj.data_node{p.Results.index, [1 2]});
        end
        function [xList, yList] = get_data(obj, device, ziNode)
            xList = []; yList = [];
            if ~isempty(obj.measured_data)
                res = cellfun(@(data_k) obj.get_data_piece(data_k, device, ziNode), obj.measured_data);
                xList = res.grid;
                yList = res.value;
            end
        end
        
        function res = get_data_piece(~, data_piece, device, ziNode)
            node = ziNode.node; idx = Miscellaneous.ziIndexNum(ziNode.index);
            signal = lower(ziNode.signal);
            switch node
                case 'demods'
                    res.grid = data_piece.(device).(node)(idx).sample{1}.grid;
                    if strcmp(signal, 'theta')
                        signal = 'phase';
                    end
                    res.value = data_piece.(device).(node)(idx).sample{1}.(signal);
                case 'pids'
                    res.grid = data_piece.(device).(node)(idx).stream.(signal){1}.grid;
                    res.value = data_piece.(device).(node)(idx).stream.(signal){1}.value;
            end
        end
        
        function plot_data(obj, device, ziNode, fig_hdl)
            if nargin == 3
                fig_hdl = figure;
            end
            [xList, yList] = obj.get_data(device, ziNode);
            
            clf(fig_hdl); ax=axes(fig_hdl);
            plot(ax, xList, yList, 'LineStyle', '-', 'Marker', '.');
                    
            xlim(ax, minmax(xList));
            xlabel(ax, ['/' obj.sweep_device '/' obj.sweep_node.toString]);
            grid(ax, 'on');
            hold(ax, 'on');
            legend(ax, ['/' device '/' ziNode.toDispString], 'location', 'best');
        end
        
        function plot_data_group(obj, fig_hdl)
            if nargin == 1
                fig_hdl = gcf;
            end
            
            group = cell2mat(obj.data_node(:, 3)); 
            maxIndex = max(group, [], 1); nRow = maxIndex(1); nCol = maxIndex(2);
            subplot_list = unique(group(:, 3));
            
            for k = 1:length(subplot_list)
                ax_k = subplot_list(k);
                nodes = find(group(:, 3) == ax_k);
                ax = subplot(nRow, nCol, ax_k, 'Parent', fig_hdl);                
                
                for q = 1:length(nodes)
                    node_q = nodes(q);
                    device_q = obj.data_node{node_q, 1}; ziNode_q = obj.data_node{node_q, 2};

                    [xList, yList] = obj.get_data(device_q, ziNode_q);
                    plot(ax, xList, yList, 'color', ax.ColorOrder(mod(node_q,7)+1, :),...
                                           'LineStyle', '-', 'Marker', '.');
                    
                    xlim(ax, minmax(obj.sweep_value));
                    xlabel(ax, ['/' obj.sweep_device '/' obj.sweep_node.toString]);
                    grid(ax, 'on');
                    hold(ax, 'on');
                end
                
                lgdString = arrayfun(@(node_q) ['/' obj.data_node{node_q, 1} '/' obj.data_node{node_q, 2}.toDispString], nodes, 'UniformOutput',false);
                legend(ax, lgdString, 'location', 'best');
                
                hold(ax, 'off');
            end
        end
    end
end

